import { retry } from '../helpers'
import {
  search,
  LongmanResultLex,
  LongmanResultRelated
} from '@/components/dictionaries/longman/engine'
import { getDefaultConfig } from '@/app-config'
import { getDefaultProfile, ProfileMutable } from '@/app-config/profiles'

describe('Dict/Longman/engine', () => {
  it('should parse lex result (love) correctly', () => {
    const profile = getDefaultProfile() as ProfileMutable
    profile.dicts.all.longman.options = {
      wordfams: false,
      collocations: true,
      grammar: true,
      thesaurus: true,
      examples: true,
      bussinessFirst: true,
      related: true
    }

    return retry(() =>
      search('love', getDefaultConfig(), profile, { isPDF: false }).then(
        searchResult => {
          expect(searchResult.audio && typeof searchResult.audio.uk).toBe(
            'string'
          )
          expect(searchResult.audio && typeof searchResult.audio.us).toBe(
            'string'
          )

          const result = searchResult.result as LongmanResultLex
          expect(result.type).toBe('lex')

          expect(result.bussinessFirst).toBe(true)
          expect(result.wordfams).toBeUndefined()
          expect(result.contemporary).toHaveLength(2)
          expect(result.bussiness).toHaveLength(0)

          result.contemporary.forEach(entry => {
            expect(entry.title.HWD.length).toBeGreaterThan(0)
            expect(entry.title.HYPHENATION.length).toBeGreaterThan(0)
            expect(entry.title.HOMNUM.length).toBeGreaterThan(0)
            expect(entry.senses.length).toBeGreaterThan(0)
            expect(typeof entry.phsym).toBe('string')
            expect(typeof entry.pos).toBe('string')
            expect(entry.freq).toHaveLength(2)
            expect(entry.level).toBeDefined()
            expect((entry.level as any).rate).toBe(3)
            expect(entry.prons).toHaveLength(2)
          })

          expect(typeof result.contemporary[0].grammar).toBe('string')
          expect(typeof result.contemporary[0].thesaurus).toBe('string')
          expect(result.contemporary[0].examples).toHaveLength(3)
          expect(result.contemporary[0].topic).toBeUndefined()

          expect(typeof result.contemporary[0].collocations).toBe('string')
          expect(typeof result.contemporary[0].thesaurus).toBe('string')
          expect(result.contemporary[1].examples).toHaveLength(4)
        }
      )
    )
  })

  it('should parse lex result (profit) correctly', () => {
    const profile = getDefaultProfile() as ProfileMutable
    profile.dicts.all.longman.options = {
      wordfams: true,
      collocations: true,
      grammar: true,
      thesaurus: true,
      examples: true,
      bussinessFirst: false,
      related: true
    }

    return retry(() =>
      search('profit', getDefaultConfig(), profile, { isPDF: false }).then(
        searchResult => {
          expect(searchResult.audio && typeof searchResult.audio.uk).toBe(
            'string'
          )
          expect(searchResult.audio && typeof searchResult.audio.us).toBe(
            'string'
          )

          const result = searchResult.result as LongmanResultLex
          expect(result.type).toBe('lex')

          expect(result.bussinessFirst).toBe(false)
          expect((result.wordfams as string).length).toBeGreaterThan(0)
          expect(result.contemporary).toHaveLength(2)
          expect(result.bussiness).toHaveLength(2)

          result.contemporary.forEach(entry => {
            expect(entry.title.HWD.length).toBeGreaterThan(0)
            expect(entry.title.HYPHENATION.length).toBeGreaterThan(0)
            expect(entry.title.HOMNUM.length).toBeGreaterThan(0)
            expect(entry.senses.length).toBeGreaterThan(0)
            expect(typeof entry.phsym).toBe('string')
            expect(typeof entry.pos).toBe('string')
            expect(entry.prons).toHaveLength(2)
          })

          result.bussiness.forEach(entry => {
            expect(entry.title.HWD.length).toBeGreaterThan(0)
            expect(entry.title.HYPHENATION.length).toBeGreaterThan(0)
            expect(entry.title.HOMNUM.length).toBeGreaterThan(0)
            expect(entry.senses.length).toBeGreaterThan(0)
            expect(typeof entry.phsym).toBe('string')
            expect(typeof entry.pos).toBe('string')
            expect(entry.freq).toHaveLength(0)
            expect(entry.level).toBeUndefined()
            expect(entry.prons).toHaveLength(0)
          })

          expect(result.contemporary[0].level).toBeDefined()
          expect((result.contemporary[0].level as any).rate).toBe(3)
          expect(typeof result.contemporary[0].collocations).toBe('string')
          expect(typeof result.contemporary[0].thesaurus).toBe('string')
          expect(result.contemporary[0].freq).toHaveLength(2)
          expect(result.contemporary[0].examples).toHaveLength(2)
          expect(typeof result.contemporary[0].topic).toBeTruthy()

          expect(result.contemporary[1].freq).toHaveLength(0)
          expect(result.contemporary[1].examples).toHaveLength(3)
          expect(result.contemporary[1].level).toBeDefined()
          expect((result.contemporary[1].level as any).rate).toBe(1)
        }
      )
    )
  })

  it('should parse related result correctly', () => {
    return retry(() =>
      search('jumblish', getDefaultConfig(), getDefaultProfile(), {
        isPDF: false
      }).then(searchResult => {
        expect(searchResult.audio).toBeUndefined()

        const result = searchResult.result as LongmanResultRelated
        expect(result.type).toBe('related')
        expect(typeof result.list).toBe('string')
      })
    )
  })
})
